package net.csdn.business.notify.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import net.csdn.business.notify.api.service.INotifyBusinessService;
import net.csdn.business.notify.common.config.AsyncThreadPoolConfig;
import net.csdn.business.notify.common.constant.CommonConstants;
import net.csdn.business.notify.common.enums.NotifyChannel;
import net.csdn.business.notify.common.enums.NotifyType;
import net.csdn.business.notify.common.enums.ResultCodeEnum;
import net.csdn.business.notify.common.exception.BusinessException;
import net.csdn.business.notify.common.mapper.NotifyBusinessMapper;
import net.csdn.business.notify.common.mapper.NotifyTemplateSetingMapper;
import net.csdn.business.notify.common.model.dto.NewNotifyBusinessDTO;
import net.csdn.business.notify.common.model.dto.UpdateNotifyBusinessDTO;
import net.csdn.business.notify.common.model.entity.NotifyBusiness;
import net.csdn.business.notify.common.model.query.NotifyBusinessQuery;
import net.csdn.business.notify.common.model.query.NotifyTemplateSetingQuery;
import net.csdn.business.notify.common.model.vo.NotifyBusinessVO;
import net.csdn.business.notify.common.model.vo.NotifyTemplateSetingVO;
import net.csdn.business.notify.common.model.vo.UserInfoVO;
import net.csdn.business.notify.feign.SystemFeignClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;


/**
 * 通知中心-业务配置Service业务层处理
 * 
 * @author ruoyi
 * @date 2023-11-27
 */
@Slf4j
@Service
public class NotifyBusinessServiceImpl extends ServiceImpl<NotifyBusinessMapper, NotifyBusiness> implements INotifyBusinessService
{

    @Resource(name= AsyncThreadPoolConfig.ASYNC_EXECUTOR_POOL_NAME)
    private ThreadPoolTaskExecutor asyncExecutor;

    @Autowired
    private SystemFeignClient userFeignClient;

    @Autowired
    private NotifyTemplateSetingMapper notifyTemplateSetingMapper;

    /**
     * 分页查询通知中心-业务配置列表
     *
     * @param query 通知中心-业务配置
     * @return 通知中心-业务配置
     */
    @Override
    public Page<NotifyBusinessVO> findPageList(NotifyBusinessQuery query) {
        //获得Page对象
        Page<NotifyBusinessVO> page = query.getPage();
        List<NotifyBusinessVO> pageList=baseMapper.findPageList(page,query);
        if(pageList!=null&&pageList.size()>0){
            List<String> userIds=new ArrayList<>();
            pageList.stream().forEach(notifyBusinessVO->{
                String createdBy=notifyBusinessVO.getCreatedBy();
                userIds.add(createdBy);
            });
            try {
                Future<Map<String, UserInfoVO>> taskA =asyncExecutor.submit(()->{
                    //批量查询用户信息
                    Map<String, UserInfoVO> userInfoMap=new HashMap<>();
                    try {
                        userInfoMap=userFeignClient.batchQuery(userIds);
                    }catch (Exception e){
                        log.info("query remote user info error");
                    }
                    return userInfoMap;
                });
                Map<String, UserInfoVO> finalUserInfoMap = taskA.get();
                pageList.stream().parallel().forEach(notifyBusinessVO->{
                    String createdBy=notifyBusinessVO.getCreatedBy();
                    UserInfoVO createdInfo = finalUserInfoMap.get(createdBy);
                    if(createdInfo!=null){
                        notifyBusinessVO.setCreatedByUserName(createdInfo.getUsername());
                        notifyBusinessVO.setCreatedByUserPhoto(createdInfo.getPhoto());
                    }
                });
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        page.setRecords(pageList);
        return page;
    }

    /**
     * 根据id查询通知中心-业务配置
     * 
     * @param id 通知中心-业务配置主键
     * @return 通知中心-业务配置
     */
    @Override
    public NotifyBusinessVO selectNotifyBusinessById(Long id)
    {
        NotifyBusinessVO notifyBusinessVO=baseMapper.selectNotifyBusinessById(id);
        if(notifyBusinessVO==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"id");
        }
        return notifyBusinessVO;
    }


    /**
     * 根据id查询通知中心-业务配置
     *
     * @param code 业务配置编码
     * @return 通知中心-业务配置
     */
    @Override
    public NotifyBusinessVO selectNotifyBusinessByCode(String code,Integer state)
    {
        return baseMapper.selectNotifyBusinessByCode(code,state);
    }

    /**
     * 查询通知中心-业务配置列表
     * 
     * @param query 通知中心-业务配置
     * @return 通知中心-业务配置
     */
    @Override
    public List<NotifyBusinessVO> selectNotifyBusinessList(NotifyBusinessQuery query)
    {
        return baseMapper.selectNotifyBusinessList(query);
    }

    /**
     * 新增通知中心-业务配置
     *
     * @param params 通知中心-业务配置
     * @return 结果
     */
    @Override
    public Integer insertNotifyBusiness(NewNotifyBusinessDTO params)
    {
        String busCode=params.getBusinessCode();
        Integer notifyType=params.getNotifyType();
        if(notifyType!= NotifyType.DIRECT.getCode()){
            String targetType=params.getTargetType();
            if(StringUtils.isBlank(targetType)){
                throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"targetType");
            }
            String act=params.getAct();
            if(StringUtils.isBlank(act)){
                throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"act");
            }
        }
        //根据业务编码判断是否存在
        NotifyBusinessVO notifyBusinessVO=baseMapper.selectNotifyBusinessByCode(busCode,null);
        if(notifyBusinessVO!=null){
            throw new BusinessException(ResultCodeEnum.NOTIFY_BUSSINESS_CODE_EXIST_ERROR);
        }
        NotifyBusiness notifyBusiness=new NotifyBusiness();
        BeanUtils.copyProperties(params,notifyBusiness);
        notifyBusiness.setCreatedBy(params.getCurUserId());
        return baseMapper.insert(notifyBusiness);
    }

    /**
     * 修改通知中心-业务配置
     *
     * @param params 通知中心-业务配置
     * @return 结果
     */
    @Override
    public Integer updateNotifyBusiness(UpdateNotifyBusinessDTO params)
    {
        Integer notifyType=params.getNotifyType();
        if(notifyType!= NotifyType.DIRECT.getCode()){
            String targetType=params.getTargetType();
            if(StringUtils.isBlank(targetType)){
                throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"targetType");
            }
            String act=params.getAct();
            if(StringUtils.isBlank(act)){
                throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"act");
            }
        }
        NotifyBusinessVO notifyBusinessVO=baseMapper.selectNotifyBusinessById(params.getId());
        if(notifyBusinessVO==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"id");
        }
        //判断修改后的编码是否存在
        LambdaQueryWrapper<NotifyBusiness> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(NotifyBusiness::getBusinessCode, params.getBusinessCode());
        queryWrapper.ne(NotifyBusiness::getId,params.getId());
        NotifyBusiness notifyBusiness=baseMapper.selectOne(queryWrapper);
        if(notifyBusiness!=null){
            throw new BusinessException(ResultCodeEnum.NOTIFY_BUSSINESS_CODE_EXIST_ERROR);
        }
        LambdaUpdateWrapper<NotifyBusiness> updateWrapper = new UpdateWrapper<NotifyBusiness>().lambda();
        updateWrapper.eq(NotifyBusiness::getId, params.getId());
        NotifyBusiness notifyBusinessUpdate=new NotifyBusiness();
        BeanUtils.copyProperties(params,notifyBusinessUpdate);
        notifyBusinessUpdate.setLastModifiedBy(params.getCurUserId());
        return baseMapper.update(notifyBusinessUpdate,updateWrapper);
    }

    /**
     * 删除通知中心-业务配置信息
     * 
     * @param id 通知中心-业务配置主键
     * @return 结果
     */
    @Override
    public Integer deleteNotifyBusinessById(Long id)
    {
        NotifyBusinessVO notifyBusinessVO=baseMapper.selectNotifyBusinessById(id);
        if(notifyBusinessVO==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"id");
        }
        //删除之前查询是否存在通知渠道的模板，如果存在，则提示先删除通知渠道的模板
        NotifyTemplateSetingQuery query=new NotifyTemplateSetingQuery();
        query.setBusinessId(id);
        List<NotifyTemplateSetingVO> templateList=notifyTemplateSetingMapper.selectNotifyTemplateSetingList(query);
        if(templateList!=null&&templateList.size()>0){
            throw new BusinessException(ResultCodeEnum.NOTIFY_BUSSINESS_DELETE_ERROR);
        }
        return baseMapper.deleteNotifyBusinessById(id);
    }
}
